#ifndef SYMBOL_TABLE_DOT_H
#define SYMBOL_TABLE_DOT_H

#include "symbol.h"

/************ WARNING *****************/
/************ WARNING *****************/
/************ WARNING *****************/
/* TABLE LIST HAS SUBSCRIPT FROM 1 TO 2^64 */
/* TABLE LIST HAS SUBSCRIPT FROM 1 TO 2^64 */
/* TABLE LIST HAS SUBSCRIPT FROM 1 TO 2^64 */
/* this leaves 0 for NULL value (not in the list) */

/* THE SYMBOL TABLE IS A STACK OF LIST */
typedef struct elem_symbol {
  struct elem_symbol* tail;
  symbol head;
} elem_symbol;

/* with such a data structure, add an element is O(0) */
typedef struct elem_table {
  struct elem_table* next;
  struct elem_symbol* list;
  struct elem_symbol* endListPtr;
  /* a bit inneficient, but we store some entry directly in the main structure */
  symbol* ptrToWordSize;
  symbol* ptrToTrueCst;
  symbol* ptrToFalseCst;
  unsigned long int size;
} elem_table;

elem_table* TABLE;

symbol* addSymbol(symbol s);

symbol* searchSymbol(char* name);

void printTable();
void initTable();
/* create a tmp variable and push it in the table */
symbol* newTmp(enum val_t varType);

void freeSymbolList(elem_symbol* list);

void pushContext();
void popContext();


struct elem_symbol* cons_s(struct elem_symbol* list, symbol s);
struct elem_symbol* nil_s();
struct elem_symbol* concat_s(struct elem_symbol* list1,struct elem_symbol* list2);

void addBunchOfSymbols(struct elem_symbol* list);
void freelist_s(struct elem_symbol* list);
symbol* getPtrToWordSize();
symbol* getPtrToTrueCst();
symbol* getPtrToFalseCst();

#endif
